/*
 * Copyright 2002-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.config;

import java.beans.PropertyEditor;
import java.security.AccessControlContext;

import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.HierarchicalBeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.metrics.ApplicationStartup;
import org.springframework.lang.Nullable;
import org.springframework.util.StringValueResolver;

/**
 * Configuration interface to be implemented by most bean factories. Provides
 * facilities to configure a bean factory, in addition to the bean factory
 * client methods in the {@link org.springframework.beans.factory.BeanFactory}
 * interface.
 *
 * <p>This bean factory interface is not meant to be used in normal application
 * code: Stick to {@link org.springframework.beans.factory.BeanFactory} or
 * {@link org.springframework.beans.factory.ListableBeanFactory} for typical
 * needs. This extended interface is just meant to allow for framework-internal
 * plug'n'play and for special access to bean factory configuration methods.
 *
 * @author Juergen Hoeller
 * @since 03.11.2003
 * @see org.springframework.beans.factory.BeanFactory
 * @see org.springframework.beans.factory.ListableBeanFactory
 * @see ConfigurableListableBeanFactory
 */

/**

 3 总结作用
 ConfigurableBeanFactory 是Spring框架中一个重要的配置接口，其核心作用是为Bean工厂提供全面的配置管理能力。
	 配置管理
		 提供对Bean工厂各种配置参数的设置和获取
		 支持类加载器、缓存策略、表达式解析器等核心配置
	 类型转换和属性编辑
		 集成Spring的类型转换系统
		 支持自定义属性编辑器注册和管理
	 生命周期管理
		 提供完整的Bean生命周期控制方法
		 支持Bean创建状态跟踪和依赖管理
	 作用域支持
		 支持标准和自定义Bean作用域
		 提供作用域Bean的管理能力
	 扩展机制
		 支持Bean后处理器注册
		 提供配置复制和别名管理功能

 2. 接口成员详解
	 常量定义
		 String SCOPE_SINGLETON = "singleton" - 标准单例作用域标识符
		 String SCOPE_PROTOTYPE = "prototype" - 标准原型作用域标识符
	 父工厂和类加载器配置
		 void setParentBeanFactory(BeanFactory parentBeanFactory) - 设置父Bean工厂
		 void setBeanClassLoader(@Nullable ClassLoader beanClassLoader) - 设置Bean类加载器
		 ClassLoader getBeanClassLoader() - 获取Bean类加载器
		 void setTempClassLoader(@Nullable ClassLoader tempClassLoader) - 设置临时类加载器
		 ClassLoader getTempClassLoader() - 获取临时类加载器
	 缓存和表达式解析配置
		 void setCacheBeanMetadata(boolean cacheBeanMetadata) - 设置是否缓存Bean元数据
		 boolean isCacheBeanMetadata() - 检查是否缓存Bean元数据
		 void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver) - 设置Bean表达式解析器
		 BeanExpressionResolver getBeanExpressionResolver() - 获取Bean表达式解析器
	 类型转换和属性编辑器配置
		 void setConversionService(@Nullable ConversionService conversionService) - 设置类型转换服务
		 ConversionService getConversionService() - 获取类型转换服务
		 void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar) - 添加属性编辑器注册器
		 void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass) - 注册自定义属性编辑器
		 void copyRegisteredEditorsTo(PropertyEditorRegistry registry) - 复制已注册的编辑器到指定注册表
		 void setTypeConverter(TypeConverter typeConverter) - 设置类型转换器
		 TypeConverter getTypeConverter() - 获取类型转换器
	 嵌入值解析和后处理器管理
		 void addEmbeddedValueResolver(StringValueResolver valueResolver) - 添加嵌入值解析器
		 boolean hasEmbeddedValueResolver() - 检查是否有嵌入值解析器
		 String resolveEmbeddedValue(String value) - 解析嵌入值
		 void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) - 添加Bean后处理器
		 int getBeanPostProcessorCount() - 获取Bean后处理器数量
	 作用域管理
		 void registerScope(String scopeName, Scope scope) - 注册作用域
		 String[] getRegisteredScopeNames() - 获取已注册作用域名称
		 Scope getRegisteredScope(String scopeName) - 根据名称获取已注册作用域
	 应用启动和安全配置
		 void setApplicationStartup(ApplicationStartup applicationStartup) - 设置应用启动监控器
		 ApplicationStartup getApplicationStartup() - 获取应用启动监控器
		 AccessControlContext getAccessControlContext() - 获取安全访问控制上下文
	 配置复制和别名管理
		 void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) - 从其他工厂复制配置
		 void registerAlias(String beanName, String alias) - 注册Bean别名
		 void resolveAliases(StringValueResolver valueResolver) - 解析所有别名
	 Bean定义和依赖管理
		 BeanDefinition getMergedBeanDefinition(String beanName) - 获取合并的Bean定义
		 boolean isFactoryBean(String name) - 检查是否为FactoryBean
		 void setCurrentlyInCreation(String beanName, boolean inCreation) - 设置Bean当前创建状态
		 boolean isCurrentlyInCreation(String beanName) - 检查Bean是否正在创建
		 void registerDependentBean(String beanName, String dependentBeanName) - 注册依赖Bean
		 String[] getDependentBeans(String beanName) - 获取依赖于指定Bean的所有Bean名称
		 String[] getDependenciesForBean(String beanName) - 获取指定Bean依赖的所有Bean名称
	 Bean销毁管理
		 void destroyBean(String beanName, Object beanInstance) - 销毁指定Bean实例
		 void destroyScopedBean(String beanName) - 销毁指定作用域Bean
		 void destroySingletons() - 销毁所有单例Bean


 3 和其他接口和类之间的关系
	 直接继承的接口
	 {@link HierarchicalBeanFactory} - 层次化Bean工厂接口
	 {@link SingletonBeanRegistry} - 单例Bean注册表接口
	 子接口
	 {@link ConfigurableListableBeanFactory} - 可配置的列表Bean工厂接口（扩展了ConfigurableBeanFactory）
	 主要实现类
	 {@link org.springframework.beans.factory.support.AbstractBeanFactory} - 抽象Bean工厂实现
	 {@link org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory} - 抽象自动装配Bean工厂实现
	 {@link org.springframework.beans.factory.support.DefaultListableBeanFactory} - 默认的可配置列表Bean工厂实现
	 关联类和接口
		{@link BeanExpressionResolver} - Bean表达式解析器
		{@link ConversionService} - 类型转换服务
		{@link PropertyEditorRegistrar} - 属性编辑器注册器
		{@link PropertyEditorRegistry} - 属性编辑器注册表
		{@link TypeConverter} - 类型转换器
		{@link StringValueResolver} - 字符串值解析器
		{@link BeanPostProcessor} - Bean后处理器
		{@link Scope} - 作用域接口
		{@link BeanDefinition} - Bean定义接口
		{@link ApplicationStartup} - 应用启动监控器



 4. 应用场景
	 Spring框架内部实现
		 ApplicationContext实现类使用该接口进行Bean工厂配置
		 各种Bean工厂实现类的基础配置接口
	 应用上下文配置
		 AbstractApplicationContext在refresh过程中配置Bean工厂
		 提供对Bean工厂完整配置能力的访问
	 自定义Bean工厂
		 开发自定义Bean工厂实现时的基础接口
		 扩展Spring容器功能时的配置入口
	 测试环境
		 在单元测试中配置和管理测试用Bean工厂
		 模拟和控制Bean工厂行为
	 框架集成
		 第三方框架与Spring集成时的配置接口
		 提供对Spring容器配置的精细控制
	 ConfigurableBeanFactory 是Spring框架实现灵活配置和扩展能力的核心组件，为Spring容器提供了强大的配置管理功能

 */
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {

	/**
	 * Scope identifier for the standard singleton scope: {@value}.
	 * <p>Custom scopes can be added via {@code registerScope}.
	 * @see #registerScope
	 */
	String SCOPE_SINGLETON = "singleton";

	/**
	 * Scope identifier for the standard prototype scope: {@value}.
	 * <p>Custom scopes can be added via {@code registerScope}.
	 * @see #registerScope
	 */
	String SCOPE_PROTOTYPE = "prototype";


	/**
	 * Set the parent of this bean factory.
	 * <p>Note that the parent cannot be changed: It should only be set outside
	 * a constructor if it isn't available at the time of factory instantiation.
	 * @param parentBeanFactory the parent BeanFactory
	 * @throws IllegalStateException if this factory is already associated with
	 * a parent BeanFactory
	 * @see #getParentBeanFactory()
	 */
	//设置此bean工厂的父工厂。注意父工厂不能更改，只能在构造函数外部设置。
	void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;

	/**
	 * Set the class loader to use for loading bean classes.
	 * Default is the thread context class loader.
	 * <p>Note that this class loader will only apply to bean definitions
	 * that do not carry a resolved bean class yet. This is the case as of
	 * Spring 2.0 by default: Bean definitions only carry bean class names,
	 * to be resolved once the factory processes the bean definition.
	 * @param beanClassLoader the class loader to use,
	 * or {@code null} to suggest the default class loader
	 */
	//设置用于加载bean类的类加载器
	void setBeanClassLoader(@Nullable ClassLoader beanClassLoader);

	/**
	 * Return this factory's class loader for loading bean classes
	 * (only {@code null} if even the system ClassLoader isn't accessible).
	 * @see org.springframework.util.ClassUtils#forName(String, ClassLoader)
	 */
	//获取用于加载bean类的类加载器
	@Nullable
	ClassLoader getBeanClassLoader();

	/**
	 * Specify a temporary ClassLoader to use for type matching purposes.
	 * Default is none, simply using the standard bean ClassLoader.
	 * <p>A temporary ClassLoader is usually just specified if
	 * <i>load-time weaving</i> is involved, to make sure that actual bean
	 * classes are loaded as lazily as possible. The temporary loader is
	 * then removed once the BeanFactory completes its bootstrap phase.
	 * @since 2.5
	 */
	//设置和获取用于类型匹配的临时类加载器
	void setTempClassLoader(@Nullable ClassLoader tempClassLoader);

	/**
	 * Return the temporary ClassLoader to use for type matching purposes,
	 * if any.
	 * @since 2.5
	 */
	//设置和获取用于类型匹配的临时类加载器
	@Nullable
	ClassLoader getTempClassLoader();

	/**
	 * Set whether to cache bean metadata such as given bean definitions
	 * (in merged fashion) and resolved bean classes. Default is on.
	 * <p>Turn this flag off to enable hot-refreshing of bean definition objects
	 * and in particular bean classes. If this flag is off, any creation of a bean
	 * instance will re-query the bean class loader for newly resolved classes.
	 */
	//控制是否缓存bean元数据，如合并的bean定义和解析的bean类。
	void setCacheBeanMetadata(boolean cacheBeanMetadata);

	/**
	 * Return whether to cache bean metadata such as given bean definitions
	 * (in merged fashion) and resolved bean classes.
	 */
	boolean isCacheBeanMetadata();

	/**
	 * Specify the resolution strategy for expressions in bean definition values.
	 * <p>There is no expression support active in a BeanFactory by default.
	 * An ApplicationContext will typically set a standard expression strategy
	 * here, supporting "#{...}" expressions in a Unified EL compatible style.
	 * @since 3.0
	 */
	//设置和获取SpEL表达式的解析策略。
	void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver);

	/**
	 * Return the resolution strategy for expressions in bean definition values.
	 * @since 3.0
	 */
	@Nullable
	BeanExpressionResolver getBeanExpressionResolver();

	/**
	 * Specify a Spring 3.0 ConversionService to use for converting
	 * property values, as an alternative to JavaBeans PropertyEditors.
	 * @since 3.0
	 */
	//设置和获取类型转换器
	void setConversionService(@Nullable ConversionService conversionService);

	/**
	 * Return the associated ConversionService, if any.
	 * @since 3.0
	 */
	@Nullable
	ConversionService getConversionService();

	/**
	 * Add a PropertyEditorRegistrar to be applied to all bean creation processes.
	 * <p>Such a registrar creates new PropertyEditor instances and registers them
	 * on the given registry, fresh for each bean creation attempt. This avoids
	 * the need for synchronization on custom editors; hence, it is generally
	 * preferable to use this method instead of {@link #registerCustomEditor}.
	 * @param registrar the PropertyEditorRegistrar to register
	 */
	//添加属性编辑器注册器
	void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);

	/**
	 * Register the given custom property editor for all properties of the
	 * given type. To be invoked during factory configuration.
	 * <p>Note that this method will register a shared custom editor instance;
	 * access to that instance will be synchronized for thread-safety. It is
	 * generally preferable to use {@link #addPropertyEditorRegistrar} instead
	 * of this method, to avoid for the need for synchronization on custom editors.
	 * @param requiredType type of the property
	 * @param propertyEditorClass the {@link PropertyEditor} class to register
	 */
	//注册自定义属性编辑器
	void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);

	/**
	 * Initialize the given PropertyEditorRegistry with the custom editors
	 * that have been registered with this BeanFactory.
	 * @param registry the PropertyEditorRegistry to initialize
	 */
	void copyRegisteredEditorsTo(PropertyEditorRegistry registry);

	/**
	 * Set a custom type converter that this BeanFactory should use for converting
	 * bean property values, constructor argument values, etc.
	 * <p>This will override the default PropertyEditor mechanism and hence make
	 * any custom editors or custom editor registrars irrelevant.
	 * @since 2.5
	 * @see #addPropertyEditorRegistrar
	 * @see #registerCustomEditor
	 */
	//设置和获取类型转换器
	void setTypeConverter(TypeConverter typeConverter);

	/**
	 * Obtain a type converter as used by this BeanFactory. This may be a fresh
	 * instance for each call, since TypeConverters are usually <i>not</i> thread-safe.
	 * <p>If the default PropertyEditor mechanism is active, the returned
	 * TypeConverter will be aware of all custom editors that have been registered.
	 * @since 2.5
	 */
	TypeConverter getTypeConverter();

	/**
	 * Add a String resolver for embedded values such as annotation attributes.
	 * @param valueResolver the String resolver to apply to embedded values
	 * @since 3.0
	 */
	//添加占位符解析器
	void addEmbeddedValueResolver(StringValueResolver valueResolver);

	/**
	 * Determine whether an embedded value resolver has been registered with this
	 * bean factory, to be applied through {@link #resolveEmbeddedValue(String)}.
	 * @since 4.3
	 */
	boolean hasEmbeddedValueResolver();

	/**
	 * Resolve the given embedded value, e.g. an annotation attribute.
	 * @param value the value to resolve
	 * @return the resolved value (may be the original value as-is)
	 * @since 3.0
	 */
	//解析给定的占位符
	@Nullable
	String resolveEmbeddedValue(String value);

	/**
	 * Add a new BeanPostProcessor that will get applied to beans created
	 * by this factory. To be invoked during factory configuration.
	 * <p>Note: Post-processors submitted here will be applied in the order of
	 * registration; any ordering semantics expressed through implementing the
	 * {@link org.springframework.core.Ordered} interface will be ignored. Note
	 * that autodetected post-processors (e.g. as beans in an ApplicationContext)
	 * will always be applied after programmatically registered ones.
	 * @param beanPostProcessor the post-processor to register
	 */
	//添加Bean后处理器
	void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);

	/**
	 * Return the current number of registered BeanPostProcessors, if any.
	 */
	//获取已注册的Bean后处理器数量
	int getBeanPostProcessorCount();

	/**
	 * Register the given scope, backed by the given Scope implementation.
	 * @param scopeName the scope identifier
	 * @param scope the backing Scope implementation
	 */
	//注册自定义作用域
	void registerScope(String scopeName, Scope scope);

	/**
	 * Return the names of all currently registered scopes.
	 * <p>This will only return the names of explicitly registered scopes.
	 * Built-in scopes such as "singleton" and "prototype" won't be exposed.
	 * @return the array of scope names, or an empty array if none
	 * @see #registerScope
	 */
	//获取所有已注册的作用域名称
	String[] getRegisteredScopeNames();

	/**
	 * Return the Scope implementation for the given scope name, if any.
	 * <p>This will only return explicitly registered scopes.
	 * Built-in scopes such as "singleton" and "prototype" won't be exposed.
	 * @param scopeName the name of the scope
	 * @return the registered Scope implementation, or {@code null} if none
	 * @see #registerScope
	 */
	//据名称获取已注册的作用域实现
	@Nullable
	Scope getRegisteredScope(String scopeName);

	/**
	 * Set the {@code ApplicationStartup} for this bean factory.
	 * <p>This allows the application context to record metrics during application startup.
	 * @param applicationStartup the new application startup
	 * @since 5.3
	 */
	void setApplicationStartup(ApplicationStartup applicationStartup);

	/**
	 * Return the {@code ApplicationStartup} for this bean factory.
	 * @since 5.3
	 */
	//设置和获取应用启动监控器，用于记录应用启动期间的指标。
	ApplicationStartup getApplicationStartup();

	/**
	 * Provides a security access control context relevant to this factory.
	 * @return the applicable AccessControlContext (never {@code null})
	 * @since 3.0
	 */
	//获取与此工厂相关的安全访问控制上下文。
	AccessControlContext getAccessControlContext();

	/**
	 * Copy all relevant configuration from the given other factory.
	 * <p>Should include all standard configuration settings as well as
	 * BeanPostProcessors, Scopes, and factory-specific internal settings.
	 * Should not include any metadata of actual bean definitions,
	 * such as BeanDefinition objects and bean name aliases.
	 * @param otherFactory the other BeanFactory to copy from
	 */
	//从给定的其他工厂复制所有相关配置。
	void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);

	/**
	 * Given a bean name, create an alias. We typically use this method to
	 * support names that are illegal within XML ids (used for bean names).
	 * <p>Typically invoked during factory configuration, but can also be
	 * used for runtime registration of aliases. Therefore, a factory
	 * implementation should synchronize alias access.
	 * @param beanName the canonical name of the target bean
	 * @param alias the alias to be registered for the bean
	 * @throws BeanDefinitionStoreException if the alias is already in use
	 */
	//为给定bean创建别名
	void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;

	/**
	 * Resolve all alias target names and aliases registered in this
	 * factory, applying the given StringValueResolver to them.
	 * <p>The value resolver may for example resolve placeholders
	 * in target bean names and even in alias names.
	 * @param valueResolver the StringValueResolver to apply
	 * @since 2.5
	 */
	//解析所有别名目标名称和已注册的别名
	void resolveAliases(StringValueResolver valueResolver);

	/**
	 * Return a merged BeanDefinition for the given bean name,
	 * merging a child bean definition with its parent if necessary.
	 * Considers bean definitions in ancestor factories as well.
	 * @param beanName the name of the bean to retrieve the merged definition for
	 * @return a (potentially merged) BeanDefinition for the given bean
	 * @throws NoSuchBeanDefinitionException if there is no bean definition with the given name
	 * @since 2.5
	 */
	//获取合并的Bean定义（考虑父子定义合并）
	BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	/**
	 * Determine whether the bean with the given name is a FactoryBean.
	 * @param name the name of the bean to check
	 * @return whether the bean is a FactoryBean
	 * ({@code false} means the bean exists but is not a FactoryBean)
	 * @throws NoSuchBeanDefinitionException if there is no bean with the given name
	 * @since 2.5
	 */
	//确定指定bean是否为FactoryBean
	boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;

	/**
	 * Explicitly control the current in-creation status of the specified bean.
	 * For container-internal use only.
	 * @param beanName the name of the bean
	 * @param inCreation whether the bean is currently in creation
	 * @since 3.1
	 */
	//显式控制指定bean的当前创建状态
	void setCurrentlyInCreation(String beanName, boolean inCreation);

	/**
	 * Determine whether the specified bean is currently in creation.
	 * @param beanName the name of the bean
	 * @return whether the bean is currently in creation
	 * @since 2.5
	 */
	//确定指定bean当前是否正在创建
	boolean isCurrentlyInCreation(String beanName);

	/**
	 * Register a dependent bean for the given bean,
	 * to be destroyed before the given bean is destroyed.
	 * @param beanName the name of the bean
	 * @param dependentBeanName the name of the dependent bean
	 * @since 2.5
	 */
	//为给定bean注册依赖bean
	void registerDependentBean(String beanName, String dependentBeanName);

	/**
	 * Return the names of all beans which depend on the specified bean, if any.
	 * @param beanName the name of the bean
	 * @return the array of dependent bean names, or an empty array if none
	 * @since 2.5
	 */
	//获取依赖于指定bean的所有bean名称
	String[] getDependentBeans(String beanName);

	/**
	 * Return the names of all beans that the specified bean depends on, if any.
	 * @param beanName the name of the bean
	 * @return the array of names of beans which the bean depends on,
	 * or an empty array if none
	 * @since 2.5
	 */
	//获取指定bean依赖的所有bean名称
	String[] getDependenciesForBean(String beanName);

	/**
	 * Destroy the given bean instance (usually a prototype instance
	 * obtained from this factory) according to its bean definition.
	 * <p>Any exception that arises during destruction should be caught
	 * and logged instead of propagated to the caller of this method.
	 * @param beanName the name of the bean definition
	 * @param beanInstance the bean instance to destroy
	 */
	//销毁给定的bean实例
	void destroyBean(String beanName, Object beanInstance);

	/**
	 * Destroy the specified scoped bean in the current target scope, if any.
	 * <p>Any exception that arises during destruction should be caught
	 * and logged instead of propagated to the caller of this method.
	 * @param beanName the name of the scoped bean
	 */
	//销毁指定作用域中的bean
	void destroyScopedBean(String beanName);

	/**
	 * Destroy all singleton beans in this factory, including inner beans that have
	 * been registered as disposable. To be called on shutdown of a factory.
	 * <p>Any exception that arises during destruction should be caught
	 * and logged instead of propagated to the caller of this method.
	 */
	//销毁工厂中的所有单例bean
	void destroySingletons();

}
